#include "parselex.h"

int currentline = 1;
int totalerr = 0;

int lines_in_prog() {
	return currentline;
}

// Parses an input file into a token list.
int parse_line(char * filename,struct tokenlist *tlist)
{
	/* okay we need to open up the input file */
	FILE *inFile;
	inFile=fopen(filename, "r");

	/* just to make sure that worked out alright */
	if(inFile==NULL) 
	{    	
		printf("Error: Cannot open file. Make sure the file exists and that you have read access to it.\n");
		return 1;
	}
	
	/* let the scanning loop begin */
	while(fgets(data, 200, inFile)!=NULL)
	{
		/* calls the line parser */
		totalerr = totalerr + parse_words(tlist);

		/* advances counter to nexlistvalt line */
		currentline++;
	}

	/* close input file when done */
	fclose(inFile);

	return 0;
}

/* parse out the "words" and convert to tokens throwing errors when needed. */
int parse_words(struct tokenlist *tlist)
{
    /* start tokenizing */  
	char* ctoken = strtok(data, " \n"); 
	union value aval;
	struct token *ptoke;
	
	while (ctoken != NULL)
	{

		/* get the opcodes out of the way */
		if(strcmp(ctoken, "MOV") == 0)
		{
			aval.op = MOV;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		else if(strcmp(ctoken, "COPY") == 0)
		{
			aval.op = COPY;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		else if(strcmp(ctoken, "SWAP") == 0)
		{
			aval.op = SWAP;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		else if(strcmp(ctoken, "JMP") == 0)
		{
			aval.op = JMP;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		else if(strcmp(ctoken, "SJMP") == 0)
		{
			aval.op = SJMP;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		else if(strcmp(ctoken, "JE") == 0)
		{
			aval.op = JE;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		else if(strcmp(ctoken, "JNE") == 0)
		{
			aval.op = JNE;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		else if(strcmp(ctoken, "ADD") == 0)
		{
			aval.op = ADD;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		else if(strcmp(ctoken, "SUB") == 0)
		{
			aval.op = SUB;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		else if(strcmp(ctoken, "MULT") == 0)
		{	
			aval.op = MULT;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		else if(strcmp(ctoken, "DIV") == 0)
		{
			aval.op = DIV;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		else if(strcmp(ctoken, "DISP") == 0)
		{
			aval.op = DISP;
			ptoke = new_op_token(currentline, aval);
			add_token(ptoke,tlist);
		}


		/* registers are similarly done */
		else if(ctoken[0]=='R' && ((ctoken[1]=='0')||(ctoken[1]=='1')||(ctoken[1]=='2')||(ctoken[1]=='3')||(ctoken[1]=='4')||(ctoken[1]=='5')||(ctoken[1]=='6')||(ctoken[1]=='7')||(ctoken[1]=='8')||(ctoken[1]=='9')))
		{
			if (ctoken[1]=='0')
				aval.r = 0;
			else if (ctoken[1]=='1')
				aval.r = 1;
			else if (ctoken[1]=='2')
				aval.r = 2;
			else if (ctoken[1]=='3')
				aval.r = 3;
			else if (ctoken[1]=='4')
				aval.r = 4;
			else if (ctoken[1]=='5')
				aval.r = 5;
			else if (ctoken[1]=='6')
				aval.r = 6;
			else if (ctoken[1]=='7')
				aval.r = 7;
			else if (ctoken[1]=='8')
				aval.r = 8;
			else
				aval.r = 9;
			ptoke = new_reg_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		 // if it starts with a number or negative sign AND has a dot (decimal point), it's a float
		else if (((ctoken[0]=='-')||(ctoken[0]=='0')||(ctoken[0]=='1')||(ctoken[0]=='2')||(ctoken[0]=='3')||(ctoken[0]=='4')||(ctoken[0]=='5')||(ctoken[0]=='6')||(ctoken[0]=='7')||(ctoken[0]=='8')||(ctoken[0]=='9'))&&(strchr(ctoken,'.') != NULL)) {
			aval.f = atof(ctoken);
			ptoke = new_float_token(currentline, aval);
			add_token(ptoke,tlist);
		}
		// if it starts with a number or a negative sign, it's an integer at this point
		else if ((ctoken[0]=='-')||(ctoken[0]=='0')||(ctoken[0]=='1')||(ctoken[0]=='2')||(ctoken[0]=='3')||(ctoken[0]=='4')||(ctoken[0]=='5')||(ctoken[0]=='6')||(ctoken[0]=='7')||(ctoken[0]=='8')||(ctoken[0]=='9')) {
			aval.i = atoi(ctoken);
			ptoke = new_int_token(currentline, aval);
			add_token(ptoke,tlist);
		}

		/* this token is not recognized */
		else
		{
			printf("Command '%s'  cannot be identified. Check that proper arguments are given.\n", ctoken);
			totalerr++;
		}
		/* get next token */  
		ctoken = strtok(NULL, " ");
	}
}
